home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DDJMAG / DDJ9005.ZIP / STEVENS.LST < prev    next >
File List  |  1990-03-23  |  10KB  |  403 lines

  1. _C PROGRAMMING COLUMN_
  2. by Al Stevens
  3.  
  4. [LISTING ONE]
  5.  
  6. /* --------- auto.h ------------ */
  7.  
  8. /*
  9.  * simple data element classes
  10.  */
  11. typedef long odometer;
  12. typedef double Dollars;
  13.  
  14. /*
  15.  * a simple date class
  16.  */
  17. typedef struct {
  18.     int mo, da, yr;
  19. } date;
  20.  
  21. /*
  22.  * Automobile class
  23.  */
  24. typedef struct {
  25.     int modelyear;
  26.     char manufacturer[20];
  27.     char license[9];
  28. } Automobile;
  29.  
  30. /*
  31.  * Trip_Record class
  32.  */
  33. typedef struct {
  34.     date trip_date;
  35.     odometer odometer_in;
  36.     odometer odometer_out;
  37.     int gallons;
  38.     Dollars cost;
  39. } Trip_Record;
  40.  
  41.  
  42. [LISTING TWO]
  43.  
  44. /* --------- auto.c ------------ */
  45.  
  46. #include <stdio.h>
  47. #include <string.h>
  48. #include <stdlib.h>
  49. #include "auto.h"
  50.  
  51. static Automobile get_car(void);
  52. static void reportauto(Automobile);
  53. char *display_date(date dt);
  54. static Trip_Record get_trip(void);
  55. static void reporttrip(Trip_Record);
  56.  
  57. void main()
  58. {
  59.     while (1)   {
  60.         /* ---- a report for each car in the input ----- */
  61.         Automobile car = get_car();
  62.         Trip_Record trip_totals = {{0,0,0},0,0,0,0};
  63.  
  64.         if (car.modelyear == 0)
  65.             break;
  66.         reportauto(car);
  67.         /* -------- prepare the detail report ---------- */
  68.         printf("\n  Date   miles  gas    cost    mpg  cost/mile");
  69.         printf("\n-------- ----- ----- -------- ----- ---------");
  70.         while (1)   {
  71.             /* ----- get the next Trip_Record from the input ---- */
  72.             Trip_Record trip = get_trip();
  73.             if (trip.trip_date.mo == 0)
  74.                 break;
  75.             /* -------- report the trip ----------- */
  76.             reporttrip(trip);
  77.             /* -------- collect totals for this car -------- */
  78.             trip_totals.odometer_in =
  79.                 max(trip_totals.odometer_in, trip.odometer_in);
  80.             trip_totals.odometer_out = trip_totals.odometer_out ?
  81.                 min(trip_totals.odometer_out, trip.odometer_out) :
  82.                 trip.odometer_out;
  83.             trip_totals.gallons += trip.gallons;
  84.             trip_totals.cost += trip.cost;
  85.         }
  86.         reporttrip(trip_totals);
  87.     }
  88. }
  89.  
  90. /* ---------- get a car's description from the input -------- */
  91. static Automobile get_car(void)
  92. {
  93.     static Automobile car;
  94.  
  95.     car.modelyear = 0;
  96.     scanf("%s", car.license);
  97.     if (strcmp(car.license, "end") != 0)    {
  98.         scanf("%d", &car.modelyear);
  99.         scanf("%s", car.manufacturer);
  100.     }
  101.     return car;
  102. }
  103.  
  104. static void reportauto(Automobile car)
  105. {
  106.     printf("\n\n%d %s License # %s\n",
  107.         car.modelyear, car.manufacturer, car.license);
  108. }
  109.  
  110. /* ------ get a trip record from the input stream ----- */
  111. static Trip_Record get_trip(void)
  112. {
  113.     date dt;
  114.     char strdate[9];
  115.     odometer oin = 0, oout = 0;
  116.     int gas = 0;
  117.     Dollars cost = 0;
  118.     static Trip_Record trip;
  119.  
  120.     dt.mo = 0;
  121.     scanf("%s", strdate);
  122.     if (strcmp(strdate, "end")) {
  123.         dt.mo = atoi(strdate);
  124.         dt.da = atoi(strdate + 3);
  125.         dt.yr = atoi(strdate + 6);
  126.         scanf("%ld", &oin);
  127.         scanf("%ld", &oout);
  128.         scanf("%d", &gas);
  129.         scanf("%lf", &cost);
  130.     }
  131.     trip.trip_date = dt;
  132.     trip.odometer_in = oin;
  133.     trip.odometer_out = oout;
  134.     trip.gallons = gas;
  135.     trip.cost = cost;
  136.     return trip;
  137. }
  138.  
  139. static void reporttrip(Trip_Record trip)
  140. {
  141.     int miles = (int) (trip.odometer_in - trip.odometer_out);
  142.     printf("\n%s %5d %5d %#8.2f %5d %#8.2f",
  143.                 trip.trip_date.mo ?
  144.                     display_date(trip.trip_date) :
  145.                     "totals  ",
  146.                 miles,
  147.                 trip.gallons,
  148.                 trip.cost,
  149.                 trip.gallons ? miles / trip.gallons : 0,
  150.                 miles ? trip.cost / miles : 0
  151.                 );
  152. }
  153.  
  154. char *display_date(date dt)
  155. {
  156.     static char d[9];
  157.     sprintf(d, "%2d-%02d-%02d", dt.mo, dt.da, dt.yr);
  158.     return d;
  159. }
  160.  
  161.  
  162. [LISTING THREE]
  163.  
  164. // auto.hpp
  165.  
  166. // -----------------------------
  167. // simple data element classes
  168. // -----------------------------
  169. typedef long odometer;
  170. typedef double Dollars;
  171.  
  172. //  -----------------------------
  173. // a simple date class
  174. // -----------------------------
  175. struct date {
  176.     int mo, da, yr;
  177.     char *display(void);
  178. };
  179.  
  180. // -----------------------------
  181. // Automobile class
  182. // -----------------------------
  183. class Automobile    {
  184. private:
  185.     int modelyear;
  186.     char *manufacturer;
  187.     char *license;
  188. public:
  189.     Automobile(char *license, int year, char *make);
  190.     Automobile();
  191.     ~Automobile();
  192.     char *display(void);
  193.     int nullcar(void) {return modelyear == 0;}
  194. };
  195.  
  196. // -----------------------------
  197. // Trip_Record class
  198. // -----------------------------
  199. class Trip_Record   {
  200. private:
  201.     date trip_date;
  202.     odometer odometer_in;
  203.     odometer odometer_out;
  204.     int gallons;
  205.     Dollars cost;
  206. public:
  207.     Trip_Record(void);
  208.     Trip_Record(date, odometer, odometer, int, Dollars);
  209.     int mileage(void) {return odometer_in - odometer_out;}
  210.     char *display(void);
  211.     int nulltrip(void) {return trip_date.mo == 0;}
  212.     void operator += (Trip_Record&);
  213. };
  214.  
  215.  
  216. [LISTING FOUR]
  217.  
  218. // auto.cpp
  219.  
  220. #include <stream.hpp>
  221. #include <string.h>
  222. #include <stdlib.h>
  223. #include "auto.hpp"
  224.  
  225. char *date::display()
  226. {
  227.     return form("%2d-%02d-%02d", mo, da, yr);
  228. }
  229.  
  230. // --------------- constructors ---------------------------
  231. Automobile::Automobile()
  232. {
  233.     modelyear = 0;
  234.     manufacturer = license = NULL;
  235. }
  236.  
  237. Automobile::Automobile(char *lic, int year, char *make)
  238. {
  239.     license = new char[strlen(lic)+1];
  240.     strcpy(license, lic);
  241.     modelyear = year;
  242.     manufacturer = new char[strlen(make)+1];
  243.     strcpy(manufacturer, make);
  244. }
  245.  
  246. // -------------- destructor -------------------
  247. Automobile::~Automobile()
  248. {
  249.     if (license != NULL)
  250.         delete license;
  251.     if (manufacturer != NULL)
  252.         delete manufacturer;
  253. }
  254.  
  255. char *Automobile::display()
  256. {
  257.     return form("%d %s License # %s",
  258.                     modelyear, manufacturer, license);
  259. }
  260.  
  261. #define max(a,b) ((a)>(b)?(a):(b))
  262. #define min(a,b) ((a)<(b)?(a):(b))
  263.  
  264. void Trip_Record::operator += (Trip_Record& trip)
  265. {
  266.     this->odometer_in = max(this->odometer_in, trip.odometer_in);
  267.     this->odometer_out = this->odometer_out ?
  268.                          min(this->odometer_out, trip.odometer_out) :
  269.                          trip.odometer_out;
  270.     this->gallons += trip.gallons;
  271.     this->cost += trip.cost;
  272. }
  273.  
  274. // --------------- constructors ---------------------------
  275. Trip_Record::Trip_Record()
  276. {
  277.     trip_date.mo = trip_date.da = trip_date.yr = 0;
  278.     odometer_in = odometer_out = 0;
  279.     gallons = 0;
  280.     cost = 0;
  281. }
  282.  
  283. Trip_Record::Trip_Record(date trdt, odometer oin, odometer oout,
  284.                           int gas, Dollars cst)
  285. {
  286.     trip_date = trdt;
  287.     odometer_in = oin;
  288.     odometer_out = oout;
  289.     gallons = gas;
  290.     cost = cst;
  291. }
  292.  
  293. char *Trip_Record::display()
  294. {
  295.     int miles = mileage();
  296.     return form("%s %5d %5d %#8.2f %5d %#8.2f",
  297.                 trip_date.mo ? trip_date.display() : "totals  ",
  298.                 miles,
  299.                 gallons,
  300.                 cost,
  301.                 gallons ? miles / gallons : 0,
  302.                 miles ? cost / miles : 0
  303.                 );
  304. }
  305.  
  306.  
  307. [LISTING FIVE]
  308.  
  309. // autorpt.cpp
  310.  
  311. #include <stream.hpp>
  312. #include <string.h>
  313. #include <stdlib.h>
  314. #include "auto.hpp"
  315.  
  316. // =========================================================
  317. // automobile operating costs system
  318. // =========================================================
  319.  
  320. // ------- prototypes
  321. static Automobile& get_car(void);
  322. static Trip_Record& get_trip(void);
  323. static void report(Automobile&);
  324. static void report(Trip_Record&);
  325.  
  326. main()
  327. {
  328.     while (1)   {
  329.         // -------- a report for each car in the input
  330.         Automobile car = get_car();
  331.         if (car.nullcar())
  332.             break;
  333.         report(car);
  334.         // -------- prepare the detail report
  335.         cout << "\n  Date   miles  gas    cost    mpg  cost/mile";
  336.         cout << "\n-------- ----- ----- -------- ----- ---------";
  337.         // ---------- a Trip_Record to hold the totals
  338.         Trip_Record trip_totals;
  339.  
  340.         while (1)   {
  341.             // -------- get the next Trip_Record from the input
  342.             Trip_Record trip = get_trip();
  343.             if (trip.nulltrip())
  344.                 break;
  345.             // -------- report the trip
  346.             report(trip);
  347.             // -------- collect totals for this car
  348.             trip_totals += trip;
  349.         }
  350.         report(trip_totals);
  351.     }
  352. }
  353.  
  354. // ---------- get a car's description from the input
  355. static Automobile& get_car(void)
  356. {
  357.     char license[7];
  358.     int modelyear = 0;
  359.     char make[25] = "";
  360.  
  361.     cin >> license;
  362.     if (strcmp(license, "end") != 0)    {
  363.         cin >> modelyear;
  364.         cin >> make;
  365.     }
  366.     Automobile *car = new Automobile(license, modelyear, make);
  367.     return *car;
  368. }
  369.  
  370. static void report(Automobile& car)
  371. {
  372.     cout << "\n\n" << car.display() << '\n';
  373. }
  374.  
  375. // ---------- get a trip record from the input stream
  376. static Trip_Record& get_trip()
  377. {
  378.     date dt;
  379.     dt.mo = 0;
  380.     char strdate[9];
  381.     odometer oin = 0, oout = 0;
  382.     int gas = 0;
  383.     Dollars cost = 0;
  384.  
  385.     cin >> strdate;
  386.     if (strcmp(strdate, "end")) {
  387.         dt.mo = atoi(strdate);
  388.         dt.da = atoi(strdate + 3);
  389.         dt.yr = atoi(strdate + 6);
  390.         cin >> oin;
  391.         cin >> oout;
  392.         cin >> gas;
  393.         cin >> cost;
  394.     }
  395.     Trip_Record *trip = new Trip_Record(dt,oin, oout, gas, cost);
  396.     return *trip;
  397. }
  398.  
  399. static void report(Trip_Record& trip)
  400. {
  401.     cout << '\n' << trip.display();
  402. }
  403.